/*
 * @(#)Solver.java    Jul 13, 2010
 *
 * Copyright 2009 Nyber Shanghai, Inc. All rights reserved.
 */

package com.lab.util.concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Future 表示异步计算的结果. 它提供了检查计算是否完成的方法, 以等待计算的完成, 并检索计算的结果. 
 *
 * @author nickevin@gmail.com
 * @version Jul 13, 2010 1:49:10 PM
 */

public class FutureSolver {

	final int threadCount;
	final List<Integer> list;
	private long sum;
	private List<Callable<Long>> taskList;

	public FutureSolver(int threadCount, List<Integer> list) {
		this.list = list;
		this.threadCount = threadCount;
		taskList = new ArrayList<Callable<Long>>(this.threadCount);
	}

	public long total() throws InterruptedException, ExecutionException {
		int size = list.size();
		int mean = size / threadCount;

		ExecutorService executor = Executors.newFixedThreadPool(threadCount);
		for (int i = 0; i < threadCount; i++) {
			int fromIndex = mean * i;
			int toIndex = i == threadCount - 1 ? size : mean * (i + 1);

			subtotal(fromIndex, toIndex);
		}

		List<Future<Long>> futureList = executor.invokeAll(taskList);
		for (Future<Long> future : futureList) {
			sum += future.get();
		}

		executor.shutdown();

		return sum;
	}

	public void subtotal(final int fromIndex, final int toIndex) {
		taskList.add(new Callable<Long>() {
			public Long call() throws Exception {
				long _result = 0;
				for (int i = fromIndex; i < toIndex; i++) {
					_result += list.get(i);
				}

				return _result;
			}
		});
	}
}